package com.yuchao.base.xyc004.prototype;

import java.util.ArrayList;
import java.util.Date;

/**
 * 测试原型模式
 */
public class CloneTest {

   // 原型模式：一个现成的对象，这个对象里面有已经设置好的值。
   // 当要新建一个对象，并且要给新建的对象赋值，而且赋值内容要跟之前的一模一样
   // 通过原型模式可以快速的创建一个对象而不需要提供专门的new()操作就可以快速完成对象的创建

   /**----------------------------------------------------------*/
   //这是最原始的方式
   //ConcretePrototype cp = new ConcretePrototype();
   //cp.setAge(18);
   //cp.setName("Tom");

   //ConcretePrototype copy = new ConcretePrototype();
   //copy.setAge(cp.getAge());
   //copy.setName(cp.getName());

   //ConcretePrototype copy = cp; 这种引用赋值并不算赋值，指向还是同一块内存地址.

   //或者用循环，用反射，确实可以的（反射性能并不高）、字节码复制方式.\

   /**
    * ----------------------------------------------------------
    */

   //浅拷贝：能够直接拷贝其实际内容的数据类型/只支持9种,八大基本数据类型+String
   //深拷贝: 可以克隆所有类型

   //场景：孙悟空拔下一嘬猴毛，轻轻一吹就会变出好多的孙悟空来。
   public static void main(String[] args) {

      ConcretePrototype cp = new ConcretePrototype();
      cp.setAge(18);
      cp.setName("Tom");

      ArrayList<String> list = new ArrayList<>();
      cp.setList(list);

      cp.setDate(new Date());
      cp.setTest(new Test());

      try {
         ConcretePrototype copy = (ConcretePrototype) cp.clone();
         System.out.println(copy.getDate() == cp.getDate());
         System.out.println(copy.getTest() == cp.getTest());
         System.out.println(copy.getList() == cp.getList()); //true  List是引用类型，这里比较结果为true，证明内存中还是同一块内存，并未做复制。

         System.out.println(copy.getAge() + "," + copy.getName() + "," + copy.getList().size()
                 + copy.getDate().getTime() + "," + copy.getTest());
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
}